import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;

public class HelloClassLoader extends  ClassLoader {
    public static void main(String[] args) throws  Exception{
        HelloClassLoader loader = new HelloClassLoader();
        Class helloClass =  loader.loadClass("Hello");

        Object hello = helloClass.newInstance();
        Method methodHello = helloClass.getDeclaredMethod("hello");
        methodHello.invoke(hello);
    }

    protected Class<?> findClass(String name) throws ClassNotFoundException {
        if(!name.equals("Hello")){
            throw new ClassNotFoundException("class "+name+" not found");
        }
        try {
            byte[] xlass = readHelloXclass();
            byte[] realBytecode = toRealBytecode(xlass);
            return defineClass(name, realBytecode, 0, realBytecode.length);
        }catch (Exception e){
            throw new ClassNotFoundException("Failed to load class Hello");
        }
    }

    private static byte[] toRealBytecode(byte[] xlass){
        byte[] byteCodes = new byte[xlass.length];
        for(int i=0; i<xlass.length; i++){
            byteCodes[i] = (byte)(255 - xlass[i]);
        }
        return byteCodes;
    }
    private static byte[] readHelloXclass() throws IOException {
        InputStream in = HelloClassLoader.class.getResourceAsStream("/Hello.xlass");
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();

        int nRead;
        byte[] data = new byte[4];

        while ((nRead = in.read(data, 0, data.length)) >= 0) {
            buffer.write(data, 0, nRead);
        }
        in.close();
        return buffer.toByteArray();
    }
}
